package unitTest;

import static org.junit.Assert.*;

import java.sql.SQLException;

import library.*;

//import org.junit.FixMethodOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
//import org.junit.runners.MethodSorters;


//@FixMethodOrder(MethodSorters.JVM)
public class TestUser {
	@Rule public ExpectedException thrown= ExpectedException.none();

	LibrarianController librarianController;
	ReaderController readerController;
    Librarian tmpLibrarian;
    Reader tmpReader;
	@Before
	public void setUp() throws SQLException{
		DaoUtil.init();
		librarianController = new LibrarianController();
        readerController = new ReaderController();

        try{
            librarianController.getLibrarian("testLibrarian");
        } catch (Exception e){
            Librarian testLibrarian = new Librarian("testLibrarian","test");
            librarianController.create(testLibrarian);
        }

        try{
            readerController.getReader("testReader");
        } catch (Exception e){
            Reader newReader = new Reader("testReader","987645432","hk");
            readerController.create(newReader);
        }
	}

	// Librarian Unit Testing

	@Test
	public void createLibrarian() throws SQLException {
		tmpLibrarian = new Librarian("tmpLibrarian", "tmp");
		boolean result = librarianController.create(tmpLibrarian);
		assertTrue(result);
	}
	@Test
	public void selectLibrarian() throws Exception {
		Librarian testLibrarian = librarianController.check("testLibrarian", "test");
		assertEquals("testLibrarian", testLibrarian.getName());
	}
	
	@Test
	public void selectLibrarianByWrongPassword() throws Exception {
		thrown.expect(Exception.class);
		thrown.expectMessage("Can not login Librarian, invalid password");
		Librarian testLibrarian = librarianController.check("testLibrarian", "test1");
		assertEquals("testLibrarian", testLibrarian.getName());
	}
	
	@Test
	public void deleteLibrarian() throws Exception {
		boolean result = librarianController.delete(librarianController.getLibrarian("testLibrarian"));
		assertTrue(result);
	}

    @Test
    /**
     *  Test Case: Try to get the Librarian that is not exist
     *  Expected Result: A User Not Find Exception should be throw
     * @throws Exception
     */
	public void notExistingLibrarian() throws Exception {
		thrown.expect(Exception.class);
		thrown.expectMessage("Librarian: testLibrarian_abc1234 not found");
		librarianController.check("testLibrarian_abc1234", "testLibrarian_abc1234");
	}	
	
	// Reader Unit Testing

    /**
     *  Test Case : select the reader: testReader
     *  Expected Result: A Reader Object with name:  testReader
     * @throws Exception
     */
	@Test
	public void selectReader() throws Exception {
		Reader testReader = readerController.getReader("testReader");
		assertEquals("testReader", testReader.getName());
	}

    @Test
	public void selectReaderWithWrongCase() throws Exception {
        thrown.expect(Exception.class);
        thrown.expectMessage("User :tEstReader not found");
		Reader testReader = readerController.getReader("tEstReader");
		assertEquals("testReader", testReader.getName());
	}
	
	
	@Test
	public void deleteReader() throws Exception {
		boolean result = readerController.delete(readerController.getReader("testReader"));
		assertTrue(result);
	}

    @Test
    public void createReader() throws SQLException {
        tmpReader = new Reader("tmpReader", "01234", "tmp");
        boolean result = readerController.create(tmpReader);
        assertTrue(result);
    }

    @After
    public void cleanup() throws SQLException {
        librarianController.delete(tmpLibrarian);
        readerController.delete(tmpReader);
    }
}
